package com.agile.leetcode.string;

/**
 * 字符串的不可变性
 *
 * @Author ChenZhangKun
 * @Date 2020/12/21 13:33
 */
public class ImmutableString {
    public static void main(String[] args) {
        // String s = new String("abc"),这句代码创建了几个对象？"abc"在常量池中构造了一个对象，new String()方法在堆区中又创建了一个对象，所以一共是两个。
        String str = new String("abc");
        System.out.println(str == "abc");
        // str.intern() 表示将对象从堆中移到常量池，因为常量池中已经有了"abc",所以直接返回引用
        System.out.println(str.intern() == "abc");
        /**
         * 在jdk6以前创建的是两个不同的对象，输出为false；而jdk7以后常量池中并不会创建新的对象，引用的是同个对象，所以输出是true
         *     jdk6之前使用intern创建对象使用的深拷贝，而在jdk7之后使用的是浅拷贝，得以重复利用堆区中的String对象。
         * 通过上面的分析，String真正重复利用字符串是在使用双引号直接创建字符串时。使用intern方法虽然可以返回常量池中的字符串引用，
         * 但是本身已经需要堆区中的一个String对象。因而我们可以得出结论：
         *     尽量使用双引号显式构建字符串；如果一个字符串需要频繁被重复利用，可以调用intern方法将他存放到常量池中。
         */
        String s = new String(new char[]{'a'});
        s.intern();
        System.out.println(s == "a");
    }
}
